package slicegen;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.Iterator;
import java.util.ListIterator;

import javax.media.j3d.BoundingBox;
import javax.media.j3d.Transform3D;
import javax.swing.JLabel;

public class FacetList extends HashSet<Triangle>
{
	public ArrayList<Triangle> getTrianglesForZ(double z)
	{
		ArrayList<Triangle> layer = new ArrayList<Triangle>();

		Iterator<Triangle> iter = iterator();

		while (iter.hasNext())
		{
			Triangle t = iter.next();

			if (t.minZ <= z && z <= t.maxZ)
				layer.add(t);
		}

		return layer;
	}

	public PolygonList getSliceForZ(ArrayList<LineSet> lineForest)
	{
		PolygonList slices = new PolygonList();

		if (lineForest == null)
			return slices;

		for (LineSet set : lineForest)
		{
			Polygon p = new Polygon();
			p.add(set.getPoints());
			
			slices.add(p);
		}

		return slices;
	}

	public ArrayList<LineSet> getLineSetsForZ(double z)
	{
		ArrayList<Triangle> facets = getTrianglesForZ(z);

		if (facets.size() == 0)
			return null;

		ArrayList<LineSet> lineForest = new ArrayList<LineSet>();

		for (Triangle triangle : facets)
		{
			Line segment = triangle.intersectWithZPlane(z, true);

			// TODO remove very short line segments, and connect the missing
			// points together
			if (segment != null && segment.length() != 0.0)
				lineForest.add(new LineSet(segment));
		}

		LineSet.resetTolerance();

		boolean ableToIncTol = true;
		while (ableToIncTol)
		{
			for (int i = 0; i < lineForest.size(); i++)
			{
				LineSet current = lineForest.get(i);

				if (mergeWithLineSet(lineForest, current))
				{
					// Start over with the new list
					i = 0;
				}
			}

			ableToIncTol = LineSet.increaseTolerance();
		}

		label.setText("Num Polygons: " + lineForest.size());
		
		for (LineSet set : lineForest)
		{
			set.simplifyPoints();
		}

		return lineForest;
	}

	private boolean mergeWithLineSet(ArrayList<LineSet> lineForest, LineSet current)
	{
		boolean changed = true;
		while (changed)
		{
			changed = false;
			for (ListIterator iter = lineForest.listIterator(); iter.hasNext();)
			{
				LineSet element = (LineSet) iter.next();

				if (current.merge(element))
				{
					// current index is now merged into current's point list
					iter.remove();

					changed = true;
				}
			}
		}

		return changed;
	}

	public void standardize(BoundingBox bounds)
	{
		double xTrans = 0, yTrans = 0, zTrans = 0;		
	}

	public void setLabel(JLabel polyLabel)
	{
		label = polyLabel;
	}

	private JLabel label;
}
